﻿using System;
using System.Web;
using System.Web.Mvc;
using ContactMvc4TB.Helpers.DynamicDataType;
using ContactMvc4TB.Helpers.HelperClasses;
using ContactMvc4TB.Helpers.HtmlHelperForViews;
using EFDataModel;
using EFDataModel.Enums;

/// <summary>
/// HTML Helper Extensions 
/// </summary>
public static class HtmlHelperExtensions
{
    #region Default HTML Helper Extensions
    /// <summary>
    /// Gibt den aktuellen CurrentController zurück.
    /// </summary>
    /// <returns>den aktuellen EController</returns>
    public static EControllers CurrentController(this HtmlHelper helper)
    {
        EControllers eControllers = (EControllers)Enum.Parse(typeof(EControllers), helper.ViewContext.RouteData.GetRequiredString(WebConstants.ControllerString));
        return eControllers;
    }

    /// <summary>
    /// Gibt einen String für Ja oder Nein für den übergebenen Boolwert zurück
    /// </summary>
    /// <param name="yesNo">Bool True für Ja | False für Nein</param>
    /// <returns>Ja oder Nein Als String wenn ein Bool übergeben wird.</returns>
    public static string DisplayForYesNo(this HtmlHelper helper, bool yesNo)
    {
        if (yesNo)
        {
            return GlobalResources.GlobalStrings.YesRESX;
        }

        return GlobalResources.GlobalStrings.NoRESX;
    }

    /// <summary>
    /// Gibt den String mit dem richtigen Namen der übergebenen KategorieID zurück
    /// </summary>
    /// <param name="userTypeId">CategoryId zu der der Name herausgesucht werden soll.</param>
    /// <returns>String mit dem Name der Kategorie</returns>
    public static string DisplayForUserType(this HtmlHelper helper, string userTypeId)
    {
        //ERmitteln um welchen Enum Wert es geht und dann den passenden String aus der Auflistung zurückgeben.
        EUserTypes eUserTypes = (EUserTypes)Enum.Parse(typeof(EUserTypes), userTypeId);
        return EFUser.UserTypes()[eUserTypes];
    }

    /// <summary>
    /// Prüft ob im TempData eine Message hinterlegt wurde und wenn ja dann wird diese angezeigt,
    /// nach einem Request ist Tempdata auch direkt wieder leer, ist nur für einen Request aktiv!
    /// http://stackoverflow.com/questions/4642845/asp-net-mvc-how-to-preserve-modelstate-errors-across-redirecttoaction
    /// </summary>
    /// <returns>HTML Konstrukt was eine Custom Message anzeigt.</returns>
    public static MvcHtmlString ShowCustomMessage(this HtmlHelper helper)
    {
        //Prüfen ob der passende Eintrag im TempData vorhanden ist.
        if (helper.ViewContext.Controller.TempData[CustomMessage.TempMessageString] != null)
        {
            //den Tempdata Wert in unsere Message casten
            Message message = (Message)helper.ViewContext.Controller.TempData[CustomMessage.TempMessageString];

            if (message != null)
            {
                //Festlegen um welchen Fehlertyp es sich handelt
                string errorClass = GetMessageTypeCssString(message.MessageType);

                //Den HTML String zusammenbauen
                string html = string.Format("<div class=\"{0}\"><button class=\"close\" data-dismiss=\"alert\" type=\"button\">×</button>{1}</div>", errorClass, message.Text);
                //Damit der HTML String auch als HTML auf der Webseite ausgegeben werden kann, diesen noch umwandeln und den Rückgabewert des Helpers anpassen.
                return MvcHtmlString.Create(html);
            }
        }

        //Keine Message hinterlegt, einfach einen leeren String zurückgeben.
        return MvcHtmlString.Empty;
    }

    /// <summary>
    /// Eigene Helper Methode für Fehler, damit diese auch richtig angezeigt werden können. Mit der Twitter API
    /// Quelle: http://stackoverflow.com/questions/5857851/custom-validationsummary-template-asp-net-mvc-3
    /// </summary>
    public static MvcHtmlString MyValidationSummary(this HtmlHelper helper, string validationMessage = "")
    {
        //Wenn das Model Valide ist, wird ein Lehrer String zurück gegeben
        if (helper.ViewData.ModelState.IsValid)
        {
            return new MvcHtmlString(string.Empty);
        }

        //zusammenbauen unserer Standard Fehlermeldung
        string retVal = "<div class='alert alert-error'><button class='close' data-dismiss='alert' type='button'>×</button>";

        //Falls etwas im Viewbag steht dann versuchen den MessageType auszulesen, im Messagetype ist das Enum Message als String hinterlegt
        //siehe z.B. UserController -> Edit Funktion, hier wird im Viewbag auch der Messagetype gesetzt um hier auf die Message einfluss zu nehmen.
        var messageType = helper.ViewContext.Controller.ViewBag.MessageType;
        if (messageType != null)
        {
            //Wenn ein Messagetype hinterlegt wurde, dann hier die passende CSS Klasse setzten, sonst wird standardmäßig von einem Error ausgegangen
            MessageTypes message = (MessageTypes)Enum.Parse(typeof(MessageTypes), messageType);
            retVal = string.Format("<div class='{0}'><button class='close' data-dismiss='alert' type='button'>×</button>", GetMessageTypeCssString(message));
        }

        //Wenn eine Validationmessage übergeben wurde, diese hier auch mit anzeigen.
        if (!string.IsNullOrEmpty(validationMessage))
        {
            retVal += validationMessage + "<br/>";
        }

        foreach (var key in helper.ViewData.ModelState.Keys)
        {
            foreach (var err in helper.ViewData.ModelState[key].Errors)
            {
                retVal += helper.Encode(err.ErrorMessage) + "<br/>";
            }
        }
        retVal += "</div>";
        return new MvcHtmlString(retVal);
    }

    #endregion

    #region Private Functions
    /// <summary>
    /// Gibt den passenden CSS Code für den übergebenen Messagetype zurück
    /// </summary>
    /// <param name="message">Der MessageType für den der passende CSS Code zurück gegeben werden soll</param>
    private static string GetMessageTypeCssString(MessageTypes message)
    {
        string errorClass = string.Empty;
        switch (message)
        {
            case MessageTypes.error:
                errorClass = "alert alert-error";
                break;
            case MessageTypes.warning:
                errorClass = "alert";
                break;

            case MessageTypes.ok:
                errorClass = "alert alert-success";
                break;

            case MessageTypes.message:
                errorClass = "alert alert-info";
                break;
            default:
                errorClass = "alert";
                break;
        }

        return errorClass;
    }

    #endregion

    #region View Specific HTML Helpers
    /// <summary>
    /// HTml Helpers die speziell für die Categorories ausgelegt sind.
    /// </summary>
    /// <returns>Instanz der Categorie Helpersklasse</returns>
    public static CategoriesHtmlHelper Categories(this HtmlHelper htmlHelper)
    {
        return new CategoriesHtmlHelper(htmlHelper);
    }

    /// <summary>
    /// HtmlHelper für das Erstellen von Links in Tabellenköpfen, zum Sortieren nach der jeweiligen passenden Spalte
    /// </summary>
    /// <param name="sortName">Der Name des Properties nach dem sortiert werden</param>
    /// <param name="linkName">Der Name der als Link angezeigt werden soll im Header</param>
    /// <returns>Instanz der Categorie HelpersKlasse</returns>
    public static SortLinksHtmlHelper TableHeaderLinks(this HtmlHelper htmlHelper, string sortName, string linkName)
    {
        return new SortLinksHtmlHelper(htmlHelper, sortName, linkName);
    }

    /// <summary>
    /// Erstellen der Brotkrumennavigation für den aktuellen Kontext in dem wir uns befinden.
    /// </summary>
    /// <returns>Instanz der BreadScrumb HelpersKlasse</returns>
    public static BreadscrumbHtmlHelper BreadScrumb(this HtmlHelper htmlHelper)
    {
        return new BreadscrumbHtmlHelper(htmlHelper);
    }

    /// <summary>
    /// Html Helper für die User
    /// </summary>
    /// <returns>Instanz der User HelpersKlasse</returns>
    public static UserHtmlHelper Users(this HtmlHelper htmlHelper)
    {
        return new UserHtmlHelper(htmlHelper);
    }

    /// <summary>
    /// Html Helper für die Arbeitszeiterfassung
    /// </summary>
    /// <returns>Instanz der Arbeitszeiterfassung HelpersKlasse</returns>
    public static WorktimeHtmlHelper Worktimes(this HtmlHelper htmlHelper)
    {
        return new WorktimeHtmlHelper(htmlHelper);
    }

    /// <summary>
    /// HtmlHelper für die Dynamischen Datentypen
    /// Dient zur Erstellung von passenden Eingabefeldern für die dynamischen Eingabetypen DynamicDataTypes
    /// Zum einen zum Bearbeiten der Daten bzw. Anzeigen der Daten für die Detailsansichten
    /// </summary>
    /// <returns>Instantz der DynamicDataTypeHtmlHelper Klasse</returns>
    public static DynamicDataTypeHtmlHelper DynamicDataType(this HtmlHelper htmlHelper)
    {
        return new DynamicDataTypeHtmlHelper(htmlHelper);
    }

    /// <summary>
    /// HtmlHelper für das Paging Element unter Listen.
    /// </summary>
    /// <returns>Instantz der PagingHelper Klasse</returns>
    public static PagingHtmlHelper Paging(this HtmlHelper htmlHelper)
    {
        return new PagingHtmlHelper(htmlHelper);
    }
    #endregion
}
